﻿using HtmlAgilityPack;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using XjjXmm.FrameWork.Cache;
using XjjXmm.FrameWork.ToolKit;

namespace XjjXmm.Spider.biquge.Bige7Com;

internal class Bige7ComSpider : ISiteSpider
{
    //https://www.zhihu.com/question/359676590/answer/1615531107

    //private readonly HttpClient _client;

    private readonly ClientBuildHelper<Bige7ComSpider> buildHelper;

    private HttpClient _client => buildHelper.Client;

    public Bige7ComSpider(ClientBuildHelper<Bige7ComSpider> buildHelper)
    {
        buildHelper.Build();
        this.buildHelper = buildHelper;
    }


    public string Domain => GetSetting().Domain;

    public SiteSetting? GetSetting()
    {
        return Setting.FindSetting<Bige7ComSpider>();
    }

    public ILogger GetLogger()
    {
        return Log.ForContext<Bige7ComSpider>();
    }

    public async IAsyncEnumerable<string> FetchNovelLinks()
    {
        // Serilog.ILogger logger = Log.Logger;
        //全本
        await foreach (var link in FetchNovelLinks(0))
        {
            yield return link;
        }

         //玄幻小说
         await foreach (var link in FetchNovelLinks(1))
         {
             yield return link;
         }

         //武侠
         await foreach (var link in FetchNovelLinks(2))
         {
             yield return link;
         }

         //都市小说
         await foreach (var link in FetchNovelLinks(3))
         {
             yield return link;
         }

         //历史小说
         await foreach (var link in FetchNovelLinks(4))
         {
             yield return link;
         }

        //网游小说
        await foreach (var link in FetchNovelLinks(5))
        {
            yield return link;
        }

        //科幻小说
        await foreach (var link in FetchNovelLinks(6))
         {
             yield return link;
         }

         //女生小说
         await foreach (var link in FetchNovelLinks(7))
         {
             yield return link;
         }

        

    }

    private async IAsyncEnumerable<string> FetchNovelLinks(int sortid)
    {
        var page = 1;
        while (true)
        {
            var diectory = await _client.GetStringAsync($"/json?sortid={sortid}&page={page}");
            var nodes = JsonConvert.DeserializeObject<List<Bige7Noveltem>>(diectory);

            if (nodes?.Count == 0)
            {
                // Logger.Debug($"Bige7ComSpider: page{page}访问结束");
                yield break;
            }

            foreach (var node in nodes)
            {
                //Logger.Debug($"{node.articlename}:{node.url_list}");

                yield return node.url_list;

                //var temp = await RedisClient.Instance.ListRightPush(keyArticle, href);
            }

            page++;

            await Task.Delay(5000);

        }
    }

    public async Task<NovelModel> FetchNovel(string url)
    {
        await Task.Delay(8000);
        var detai = await _client.GetStringAsync(url);

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(detai);

        var main = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='info']");
        var title = main.SelectSingleNode(".//h1").InnerText;
        var author = main.SelectSingleNode(".//div[@class='small']/span").InnerText.Replace("&nbsp;", "").Replace("作者：", "");

        var updateTime = main.SelectSingleNode(".//span[3]").InnerText.Replace("更新：", "").Trim().ToDateTime();
        var lastChapter = main.SelectSingleNode(".//span[4]/a").InnerText.Trim();

        ////html/body/div[5]/div[1]/text()
        var category = main.SelectSingleNode("//div[@class='book']/div[@class='path wap_none']/text()").InnerText.Replace("&gt;", ">").Split('>')[1].Trim();

        var isInstalment = main.SelectSingleNode(".//div[@class='small']/span[2]").InnerText.Contains("完本");

        var intro = main.SelectSingleNode("./div[@class='intro']").InnerHtml;
        var imgUrl = main.SelectSingleNode("./div[@class='cover/img']").Attributes["src"].Value;

        var novel = new NovelModel()
        {
            Title = title,
            Author = author,
            Category = category,
            UpdateTime = updateTime,
            LastChapter = lastChapter,
            IsInstalment = isInstalment,
            Intro = intro,
            ImgUrl = imgUrl
        };

        return novel;
    }

    public async Task<string> FetchContent(string url)
    {

        await Task.Delay(5000);
        var result = await _client.GetAsync(url);
        var detai = await result.Content.ReadAsStringAsync();

        if (result.StatusCode == HttpStatusCode.ServiceUnavailable && detai.Contains("本章由于字数太少，暂不显示"))
        {
            return "";
        }

        // result.EnsureSuccessStatusCode ();
        // var detai = await _client.GetStringAsync(url);

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(detai);

        //*[@id="wrapper"]/div[4]/div/div[2]/h1
        var title = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='content']/h1").InnerText.Trim();
        var content = htmlDoc.DocumentNode.SelectSingleNode("//div[@id='chaptercontent']").InnerHtml;
        //*[@id="content"]

        return content;


    }


    /// <summary>
    /// 某一个小说的所有章节
    /// </summary>
    /// <param name="url"></param>
    /// <returns></returns>
    public async IAsyncEnumerable<Chapter> FetchChapters(string url)
    {
        GetLogger().Information(Domain + ": 开始抓取章节列表：" + url);

        var detai = await _client.GetStringAsync(url);

        var htmlDoc = new HtmlDocument();
        htmlDoc.LoadHtml(detai);
        var paras = htmlDoc.DocumentNode.SelectNodes("//div[@class='listmain']/dl//dd"); //*[@id="list"]/dl/dd[1]/a
        foreach (var item in paras)
        {
            var link = item.SelectSingleNode(".//a");

            var href = link.Attributes["href"].Value;
            var text = link.InnerText;

            if (href.Contains("javascript"))
            {
                continue;
            }

            yield return new Chapter
            {
                Title = text,
                Link = href
            };
            //yield return new
            //{
            //    title = title,
            //    author = author,
            //    chapter = text,
            //    href = href
            //};
            // await RedisClient.Instance.ListRightPush(key, href);

            // await RedisClient.Instance.HashSet(key, text + "_href", href);
            // _logger.LogDebug($"{text}:{href}");
        }
        //*[@id="info"]
    }




}
